package com.similarity;

import java.util.Iterator;
import java.util.Map;

import com.model.DataModel;
import com.model.StructuredContextDataModel;

public class ContextSimilarity {

	private StructuredContextDataModel datamodel;
	
	public ContextSimilarity(DataModel datamodel)
	{
		this.datamodel=(StructuredContextDataModel)datamodel;
	}
	
	public Double calculateSimilarity(String contextDimension,String contextValue,String currentContext) throws Exception {
		
 		Double similarity = null;
		Map<Integer, Double> currContextMap;
		Map<Integer, Double> consideredContextMap;
		Boolean hasCommonImages = false;
		
		try {
			currContextMap = getContextVectors(contextDimension,currentContext);
			consideredContextMap = getContextVectors(contextDimension,contextValue);
			if (currContextMap.keySet().isEmpty() || consideredContextMap.keySet().isEmpty()) {
				//new context value
				return 0.0d;
			}
			Iterator<Integer> iterCheck = currContextMap.keySet().iterator(); 
			while (iterCheck.hasNext()) {
				Integer imageID  = (Integer)iterCheck.next();
				if(consideredContextMap.containsKey(imageID))
					{
						hasCommonImages = true;
						break;
					}
				}
			
			if(!hasCommonImages)return 0.0;
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}
		
		Double upperPortion = 0.0d;
		Double latterPortion = 0.0d;
		Iterator<Integer> iter = currContextMap.keySet().iterator();
		while (iter.hasNext()) {
			Integer  ImageID = (Integer) iter.next();
			if (consideredContextMap.containsKey(ImageID)) {
				Double Val = currContextMap.get(ImageID)*consideredContextMap.get(ImageID);
				upperPortion = upperPortion + Val;
			}			
		} 
		
		Double MagnitudeCurr = 0.0d,MagnitudeCon = 0.0d;
		Iterator<Double> newIter =  currContextMap.values().iterator();
		while (newIter.hasNext()) {	
			float t1=(newIter.next().floatValue());
			float tmp = t1*t1;
			MagnitudeCurr = MagnitudeCurr + tmp;
			}	
		MagnitudeCurr = Math.sqrt(MagnitudeCurr);
		newIter =  consideredContextMap.values().iterator();
		while (newIter.hasNext()) {
			float t2=(newIter.next().floatValue());
			float tmpr = t2*t2;
			MagnitudeCon = MagnitudeCon + tmpr;
			}	
		MagnitudeCon = Math.sqrt(MagnitudeCon);
		latterPortion = (MagnitudeCon * MagnitudeCurr);
		
		if(latterPortion!=0)
		{
			similarity = upperPortion/latterPortion;
		}
		if(latterPortion==0.0)
		{
				similarity=1.0;
		}
		//}else
		//{
			//similarity=0.0;
		//}

		
		return similarity;
	}
	
	private Map<Integer, Double> getContextVectors(String contextDimension,String contextValue) throws Exception {
		try {
			return datamodel.GetContextVector(contextDimension, contextValue);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw e;
		}
	}
	
	
}
